﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Text;
using System.Data.Entity;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using Aga.GestionDeArchivos.Domain;
using Aga.GestionDeArchivos.Domain.Entities;
using System.Web;
using System.Collections;
using System.Transactions;

namespace Aga.GestionDeArchivos.Storage
{
    public abstract class RepositoryBase<T>
        where T : class, IDomainEntity
    {
        public AgaEntities Context { get; private set; }

        protected abstract Action<T> AddToContext(T entity);
        protected abstract ObjectSet<T> EntitySet { get; }

        /// <summary>
        /// Initializes a new instance of the <see cref="RepositoryBase&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="context">The context.</param>
        public RepositoryBase(AgaEntities context)
        {
            this.Context = context;
        }

        /// <summary>
        /// Gets all entityes.
        /// </summary>
        /// <returns></returns>
        public virtual IQueryable<T> GetAll()
        {
            var entities = EntitySet;
            
            return entities;
        }

        /// <summary>
        /// Gets the entity by its id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public virtual T GetById(Int32 id)
        {
            var entity = EntitySet.Where(e => e.Id.Equals(id)).FirstOrDefault();

            return entity;
        }
            
        /// <summary>
        /// Saves the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        public virtual void Save(T entity)
        {
            using (var ts = new TransactionScope())
            {
                var user = GetCurrentUser();

                entity.ModificationDate = DateTime.Now;
                entity.ModificationUser = user;

                if (entity.Id.Equals(default(Int32)))
                {
                    entity.CreationDate = DateTime.Now;
                    entity.CreationUser = user;

                    AddToContext(entity).Invoke(entity);
                }

                try
                {
                    Context.SaveChanges();

                    ts.Complete();
                }
                catch
                {
                    throw;
                }
            }
        }

        /// <summary>
        /// Gets the current user.
        /// </summary>
        /// <returns></returns>
        public string GetCurrentUser()
        {
            string user = "anonymous";

            if (HttpContext.Current != null)
                user = HttpContext.Current.User.Identity.Name;

            return user;
        }

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        public virtual void Delete(T entity)
        {
            using (var ts = new TransactionScope())
            {
                try
                {
                    Context.DeleteObject(entity);
                    Context.SaveChanges();

                    ts.Complete();
                }
                catch
                {
                    throw;
                }

            }
        }
    }
}
